package com.bifang.module.file.core.common.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.domain.AppResponse;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.module.base.common.constants.BaseCache;
import com.bifang.module.base.common.enums.ErrorEnum;
import com.bifang.module.base.common.vo.application.ApplicationVO;
import com.bifang.module.file.common.enums.FileClassCodeEnum;
import com.bifang.module.file.common.enums.FileReqTypeEnum;
import com.bifang.module.file.common.enums.FileSecrecyLevelEnum;
import com.bifang.module.file.common.util.FileDiffUtil;
import com.bifang.module.file.common.vo.*;
import com.bifang.module.file.common.vo.fileAppRead.FileAppReadVO;
import com.bifang.module.file.core.biz.FileClassIntegration;
import com.bifang.module.file.core.biz.FileEnvIntegration;
import com.bifang.module.file.core.biz.FileInfoIntegration;
import com.bifang.module.file.core.common.FileLogIntegration;
import com.bifang.module.file.core.common.FileService;
import com.bifang.module.file.core.util.FileCommonUtil;
import com.bifang.module.file.core.util.FileServiceUtil;
import com.bifang.module.file.dao.model.FileInfo;
import com.bifang.module.file.dao.service.FileAppReadService;
import com.bifang.module.file.dao.service.FileInfoService;
import com.bifang.module.system.core.dao.service.SysApplicationService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

/** 文件服务 */
@Service
public class FileServiceImpl implements FileService {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    SysApplicationService applicationService;
    // 临时文件目录
    @Value("${spring.servlet.multipart.location}")
    private String tmpPath;

    @Autowired private FileClassIntegration fileClassIntegration;
    @Autowired private FileServiceUtil fileServiceUtil;
    @Autowired private FileInfoIntegration fileInfoIntegration;
    @Autowired private FileCommonUtil fileCommonUtil;
    @Autowired private FileEnvIntegration fileEnvIntegration;
    @Autowired private FileLogIntegration fileLogIntegration;
    @Autowired private FileInfoService fileInfoService;
    @Autowired private FileAppReadService fileAppReadService;
    @Override
    public FileUploadResVO upload(
            FileInfoVO fileInfoVO, MultipartFile file) {
        FileUploadResVO fileUploadResVO = new FileUploadResVO();
        fileUploadResVO.setFlag(true);
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.UPLOAD.getType());
        try {
            this.setInfo(fileInfoVO, fileLogVO);
            // 获取文件分类信息
            FileClassVO fileClassVO = this.getFileClass(fileInfoVO);
            if (StringUtils.isBlank(fileInfoVO.getFileName())) {
                fileInfoVO.setFileName(file.getOriginalFilename());
            } else {
                if (fileInfoVO.getFileName().indexOf(".") <= 0) {
                    throw new AppException("文件名必须包含文件类型后缀");
                }
            }
            fileUploadResVO.setName(fileInfoVO.getFileName());
            BeanUtil.copyProperties(fileClassVO, fileInfoVO);
            fileLogVO.setFileName(fileInfoVO.getFileName());
            if (StringUtils.isBlank(fileInfoVO.getFileSuffix())) {
                fileInfoVO.setFileSuffix(this.getFileSuffix(fileInfoVO.getFileName()));
            }
            if (fileInfoVO.getFileSize() == null || fileInfoVO.getFileSize() == 0) {
                fileInfoVO.setFileSize(file.getSize());
            }

            //上传权限判断
            this.checkUpload(fileInfoVO);

            // 保存文件
            fileServiceUtil.upload(fileClassVO, fileInfoVO, file);

        } catch (AppException e) {
            logger.error("上传异常：", e);
            fileUploadResVO.setFlag(false);
            fileUploadResVO.setMsg(e.getMsg());
        } catch (Exception e) {
            logger.error("上传异常：", e);
            fileUploadResVO.setFlag(false);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileUploadResVO.setMsg(msg);
        }
        fileUploadResVO.setFileId(fileInfoVO.getFileId());
        fileUploadResVO.setShowId(fileInfoVO.getShowId());
        fileLogVO.setFileId(fileUploadResVO.getFileId());
        if (fileUploadResVO.getFlag()) {
            fileLogVO.setCode(0);
        } else {
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(fileUploadResVO.getMsg());
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        return fileUploadResVO;
    }

    /** base64文件上传 */
    @Override
    public FileUploadResVO uploadBase64(FileInfoVO fileInfoVO) {

        FileUploadResVO fileUploadResVO = new FileUploadResVO();
        fileUploadResVO.setFlag(true);
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.UPLOAD.getType());
        try {
            this.setInfo(fileInfoVO, fileLogVO);

            if (StringUtils.isNotBlank(fileInfoVO.getFileName())) {
                if (fileInfoVO.getFileName().indexOf(".") <= 0) {
                    throw new AppException("文件名必须包含文件类型后缀");
                }
                if (StringUtils.isBlank(fileInfoVO.getFileSuffix())) {
                    fileInfoVO.setFileSuffix(this.getFileSuffix(fileInfoVO.getFileName()));
                }
            }

            // base64解码
            if (!isBase64(fileInfoVO.getFile())) {
                throw new AppException("不是base64格式数据");
            }
            byte[] bytes = Base64.decode(fileInfoVO.getFile());
            if (fileInfoVO.getFileSize() == null || fileInfoVO.getFileSize() == 0) {
                fileInfoVO.setFileSize((long) FileDiffUtil.getValidLength(bytes));
            }
            // 获取文件分类信息
            FileClassVO fileClassVO = this.getFileClass(fileInfoVO);
            if (fileClassVO == null) {
                throw new AppException("找不到对应文件分类");
            }
            BeanUtil.copyProperties(fileClassVO, fileInfoVO);
            //上传权限判断
            this.checkUpload(fileInfoVO);
            // 保存文件
            fileServiceUtil.upload(fileClassVO, fileInfoVO, bytes);
        } catch (AppException e) {
            logger.error("上传异常：", e);
            fileUploadResVO.setFlag(false);
            fileUploadResVO.setMsg(e.getMsg());
        } catch (Exception e) {
            logger.error("上传异常：", e);
            fileUploadResVO.setFlag(false);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileUploadResVO.setMsg(msg);
        }
        fileUploadResVO.setFileId(fileInfoVO.getFileId());
        fileUploadResVO.setShowId(fileInfoVO.getShowId());
        fileLogVO.setFileId(fileUploadResVO.getFileId());
        if (fileUploadResVO.getFlag()) {
            fileLogVO.setCode(0);
        } else {
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(fileUploadResVO.getMsg());
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        return fileUploadResVO;
    }

    private boolean isBase64(String str) {
        String base64Pattern =
                "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
        return Pattern.matches(base64Pattern, str);
    }

    @Override
    public FileLogVO dwonload(FileInfoVO fileInfoVO, HttpServletResponse response,String signature,String timestamp) {
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.DOWNLOAD.getType());
        try {
            setInfo(fileInfoVO, fileLogVO);
            fileLogVO.setFileName(fileInfoVO.getShowId());
            FileInfoVO oldVO = fileInfoIntegration.getFileInfoDetail(fileInfoVO.getShowId());
            if (oldVO == null) {
                throw new AppException("文件不存在");
            }
            fileCommonUtil.checkSign(fileInfoVO.getAppId().toString(),signature,timestamp,oldVO.getFileClassCode());
            //判断获取权限
            this.checkDownload(fileInfoVO,oldVO.getUpAppId());

            fileLogVO.setFileId(oldVO.getFileId());
            fileLogVO.setFileName(oldVO.getFileName());
            // 获取文件分类信息
            FileClassVO fileClassVO =
                    fileClassIntegration.getFileClassDetail(oldVO.getFileClassCode());
            if (fileClassVO == null) {
                throw new AppException("找不到对应文件分类");
            }
            if (oldVO.getFileEnvId() == null) {
                throw new AppException("数据异常：环境信息为空");
            }
            // 获取文件分类信息
            FileEnvVO fileEnvVO = fileEnvIntegration.getFileEnvDetail(oldVO.getFileEnvId());
            if (fileEnvVO == null) {
                throw new AppException("找不到对应文件服务环境信息");
            }
            BeanUtil.copyProperties(fileEnvVO, fileClassVO);
            BeanUtil.copyProperties(fileClassVO, oldVO);
            if (oldVO.getForceFlag() == null) {
                oldVO.setForceFlag(false);
            }
            oldVO.setAccessToken(fileInfoVO.getAccessToken());
            fileServiceUtil.download(fileClassVO, oldVO, response);
        } catch (AppException e) {
            logger.error("下载异常：", e);
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(e.getMsg());
        } catch (Exception e) {
            logger.error("下载异常：", e);
            fileLogVO.setCode(-1);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileLogVO.setMessage(msg);
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        return fileLogVO;
    }

    @Override
    public AppResponse getBase64(FileInfoVO fileInfoVO,String signature,String timestamp) {
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.DOWNLOAD.getType());
        String base64 = "";
        try {
            setInfo(fileInfoVO, fileLogVO);
            fileLogVO.setFileName(fileInfoVO.getShowId());
            FileInfoVO oldVO = fileInfoIntegration.getFileInfoDetail(fileInfoVO.getShowId());
            if (oldVO == null) {
                throw new AppException("文件不存在");
            }
            fileCommonUtil.checkSign(fileInfoVO.getAppId().toString(),signature,timestamp,oldVO.getFileClassCode());
            //判断获取权限
            this.checkDownload(fileInfoVO,fileInfoVO.getAppId());

            fileLogVO.setFileId(oldVO.getFileId());
            fileLogVO.setFileName(oldVO.getFileName());
            if (oldVO.getFileSize() != null) {
                fileCommonUtil.checkBase64(oldVO.getFileSize());
            }
            // 获取文件分类信息
            FileClassVO fileClassVO =
                    fileClassIntegration.getFileClassDetail(oldVO.getFileClassCode());
            if (fileClassVO == null) {
                throw new AppException("找不到对应文件分类");
            }
            if (oldVO.getFileEnvId() == null) {
                throw new AppException("数据异常：环境信息为空");
            }
            // 获取文件分类信息
            FileEnvVO fileEnvVO = fileEnvIntegration.getFileEnvDetail(oldVO.getFileEnvId());
            if (fileEnvVO == null) {
                throw new AppException("找不到对应文件服务环境信息");
            }
            BeanUtil.copyProperties(fileEnvVO, fileClassVO);
            BeanUtil.copyProperties(fileClassVO, oldVO);
            if (oldVO.getForceFlag() == null) {
                oldVO.setForceFlag(false);
            }
            oldVO.setAccessToken(fileInfoVO.getAccessToken());
            base64 = fileServiceUtil.getBase64(fileClassVO, oldVO);
        } catch (AppException e) {
            logger.error("下载异常：", e);
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(e.getMsg());
        } catch (Exception e) {
            logger.error("下载异常：", e);
            fileLogVO.setCode(-1);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileLogVO.setMessage(msg);
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        if (fileLogVO.getCode() == 0) {
            return AppResponse.successData(base64);
        } else {
            return AppResponse.error(fileLogVO.getCode(), fileLogVO.getMessage());
        }
    }

    /** 文件删除 */
    @Override
    public FileLogVO deleteFile(FileInfoVO fileInfoVO,String signature,String timestamp) {
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.DELETE.getType());
        try {
            setInfo(fileInfoVO, fileLogVO);
            FileInfoVO oldVO = fileInfoIntegration.getFileInfoDetail(fileInfoVO.getShowId());
            if (oldVO == null) {
                fileLogVO.setFileName(fileInfoVO.getShowId());
                fileLogIntegration.saveFileLog(fileLogVO);
                return fileLogVO;
            }
            fileCommonUtil.checkSign(fileInfoVO.getAppId().toString(),signature,timestamp,oldVO.getFileClassCode());
            if (oldVO.getUpAppId() - fileInfoVO.getUpAppId() != 0) {
                throw new AppException("文件不是该应用（" + fileInfoVO.getAppId() + "）上传，不能删除");
            }
            FileInfoVO query = new FileInfoVO();
            query.setFileMd5(oldVO.getFileMd5());
            query.setFilePath(oldVO.getFilePath());
            query.setFileClassCode(oldVO.getFileClassCode());
            query.setUpAppId(fileInfoVO.getUpAppId());
            PageInfo<FileInfoVO> md5Page = fileInfoIntegration.getFileInfoList(query);
            List<FileInfoVO> md5List = md5Page.getList();
            if (!CollectionUtils.isEmpty(md5List)) {
                if (md5List.size() > 1) {
                    fileInfoIntegration.deleteFileInfo(oldVO.getFileId(),oldVO.getTableName(),oldVO.getShowId());
                    fileLogIntegration.saveFileLog(fileLogVO);
                    return fileLogVO;
                }
            }
            fileLogVO.setFileId(oldVO.getFileId());
            fileLogVO.setFileName(oldVO.getFileName());

            if (oldVO.getFileEnvId() == null) {
                throw new AppException("数据异常：环境信息为空");
            }
            // 获取文件分类信息
            FileEnvVO fileEnvVO = fileEnvIntegration.getFileEnvDetail(oldVO.getFileEnvId());
            if (fileEnvVO == null) {
                throw new AppException("找不到对应文件服务环境信息");
            }
            BeanUtil.copyProperties(fileEnvVO, oldVO);
            fileServiceUtil.deleteFile(oldVO);
        } catch (AppException e) {
            logger.error("删除异常：", e);
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(e.getMsg());
        } catch (Exception e) {
            logger.error("删除异常：", e);
            fileLogVO.setCode(-1);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileLogVO.setMessage(msg);
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        return fileLogVO;
    }

    @Override
    public FileLogVO showFile(FileInfoVO fileInfoVO, HttpServletResponse response,Boolean isSendRedirect,String signature,String timestamp) {
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setFileReqType(FileReqTypeEnum.SHOW.getType());
        try {
            if (StringUtils.isBlank(fileInfoVO.getShowId())) {
                throw new AppException("查询的文件id不能传空");
            }
            FileInfoVO info = fileInfoIntegration.getFileInfoDetail(fileInfoVO.getShowId());
            if (info == null) {
                throw new AppException("查询不到对应文件信息");
            }
            fileInfoVO.setFileClassCode(info.getFileClassCode());
            setInfo(fileInfoVO, fileLogVO);
            fileLogVO.setFileName(fileInfoVO.getShowId());


            fileCommonUtil.checkSign(fileInfoVO.getAppId().toString(),signature,timestamp,info.getFileClassCode());
            //判断获取权限
            this.checkDownload(fileInfoVO,info.getUpAppId());

            fileLogVO.setFileId(info.getFileId());
            fileLogVO.setFileName(info.getFileName());
            if (info.getFileEnvId() == null) {
                throw new AppException("数据异常：文件环境信息未配置");
            }
            FileEnvVO fileEnvVO = fileEnvIntegration.getFileEnvDetail(info.getFileEnvId());
            if (fileEnvVO == null) {
                throw new AppException("数据异常：文件环境信息未配置");
            }

            BeanUtil.copyProperties(fileEnvVO, info);
            fileServiceUtil.showFile(info, response,isSendRedirect);

        } catch (AppException e) {
            logger.error("获取文件异常：", e);
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(e.getMsg());
        } catch (Exception e) {
            logger.error("获取文件异常：", e);
            fileLogVO.setCode(-1);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileLogVO.setMessage(msg);
        }
        //查看文件日志不再记录
        //fileLogIntegration.saveFileLog(fileLogVO);
        return fileLogVO;
    }

    /** 设置文件相关信息 */
    private void setInfo(FileInfoVO fileInfoVO, FileLogVO fileLogVO) {
        fileLogVO.setFileId(fileInfoVO.getFileId());
        fileLogVO.setBegTime(new Date());
        fileLogVO.setAppId(fileInfoVO.getAppId());
        fileLogVO.setCode(0);
        fileLogVO.setMessage("成功");
        fileLogVO.setReqIp(fileInfoVO.getReqIp());
        fileLogVO.setReqTime(new Date());
        fileLogVO.setName(fileInfoVO.getUploader());
        fileLogVO.setUserId(fileInfoVO.getUploaderId());
        if (fileInfoVO.getAppId()==null) {
            throw new AppException("appId不能为空！");
        }
        // 获取调用方信息
        ApplicationVO applicationVO =
                applicationService.getApplicationByAppId(fileInfoVO.getAppId());
        if (applicationVO == null) {
            throw new AppException("调用方未注册！");
        }
        fileLogVO.setAppId(applicationVO.getAppId());
        fileLogVO.setAppName(applicationVO.getAppName());
        // token校验
        checkTokenAndScope(applicationVO, fileInfoVO.getAccessToken(),fileLogVO.getFileReqType());
        fileInfoVO.setUpAppId(applicationVO.getAppId());
        fileInfoVO.setUpAppName(applicationVO.getAppName());
        if (StringUtils.isBlank(fileInfoVO.getFileClassCode())) {
            fileInfoVO.setFileClassCode(FileClassCodeEnum.OTHER.getType());
        }
        fileLogVO.setFileClassCode(fileInfoVO.getFileClassCode());
        //设置文件保密级别
        if(StringUtils.isBlank(fileInfoVO.getSecrecyLevel())){
            String fileClassCode = fileInfoVO.getFileClassCode();
            FileClassVO fileClassDetail = fileClassIntegration.getFileClassDetail(fileClassCode);
            fileInfoVO.setSecrecyLevel(fileClassDetail.getSecrecyLevel());
        }        
        if (fileInfoVO.getUpTime() == null) {
            fileInfoVO.setUpTime(new Date());
        }
        if (fileInfoVO.getForceFlag() == null) {
            fileInfoVO.setForceFlag(false);
        }
    }

    /** 获取文件分类信息 */
    @Override
    public FileClassVO getFileClass(FileInfoVO fileInfoVO) {
        FileClassVO fileClassVO =
                fileClassIntegration.getFileClassDetail(
                        fileInfoVO.getFileClassCode(), fileInfoVO.getUpAppId());
        if (fileClassVO == null) {
            throw new AppException("找不到对应文件分类");
        }
        fileInfoVO.setStorageGroup(fileClassVO.getStorageGroup());
        if (StringUtils.isBlank(fileClassVO.getEncryptionFlag())) {
            fileInfoVO.setEncryptionFlag(BoolEnum.FALSE.getType());
        } else {
            fileInfoVO.setEncryptionFlag(fileClassVO.getEncryptionFlag());
        }
        return fileClassVO;
    }

    /** 判断是否允许上传 */
    public void checkUpload(FileInfoVO fileInfoVO) {
        Long appId = fileInfoVO.getAppId();
        String fileClassCode = fileInfoVO.getFileClassCode();

        FileClassVO fileClassVO = fileClassIntegration.getFileClassDetail(fileClassCode,appId);
        if(fileClassVO==null){
            throw new AppException("应用APPID:"+appId+"无权限上传分类编码为"+fileClassCode+"的文件");
        }
        if (!fileClassVO.getAppHasScope()){
            throw new AppException("应用APPID:"+appId+"无权限上传分类编码为"+fileClassCode+"的文件");
        }
        if (BoolEnum.FALSE.getType().equalsIgnoreCase(fileClassVO.getStatus())){
            throw new AppException("上传分类编码"+fileClassCode+"已无效");
        }
        Long expireTime = fileClassVO.getExpireTime();
        if (expireTime!=null&&expireTime>0&&expireTime<System.currentTimeMillis()){
            throw new AppException("应用APPID:"+appId+"上传分类"+fileClassCode+"的文件,授权已过期");
        }

    }

    /** 判断是否有读取权限 */
    public void checkDownload(FileInfoVO fileInfoVO,Long permitAppId) {
        Long appId=fileInfoVO.getAppId();
        String fileClassCode=fileInfoVO.getFileClassCode();
        String secrecyLevel=fileInfoVO.getSecrecyLevel();
        if (StringUtils.isBlank(secrecyLevel)){
            //默认为公开
            secrecyLevel=FileSecrecyLevelEnum.open.getType();

        }
        //文件上传人读取不控制读取权限,公开的文件不控制权限
        if(!FileSecrecyLevelEnum.open.getType().equalsIgnoreCase(secrecyLevel)&&!appId.equals(permitAppId)){
            //判断文件是否有单独授权，有单独授权的直接能访问

            FileAppReadVO fileAppReadVO=fileAppReadService.getFileReadDetail(fileClassCode,appId);
            if (fileAppReadVO==null){
                throw new AppException("应用APPID:"+appId+"无权限获取"+fileClassCode+"分类的文件");
            }
            String appSercecy=fileAppReadVO.getSecrecyLevel();
            if (StringUtils.isBlank(appSercecy)){
                appSercecy=FileSecrecyLevelEnum.open.getType();
            }
            if (Integer.parseInt(secrecyLevel)<=Integer.parseInt(appSercecy)){
                throw new AppException("应用允许查看的等级小于该文件最低要求的等级，请申请授权访问");
            }
            if (fileAppReadVO.getExpireTime()!=null){
                Long expireTime = fileAppReadVO.getExpireTime().getTime();
                if (expireTime<System.currentTimeMillis()){
                    throw new AppException("应用授权访问该分类文件时间已到期");
                }
            }

        }
    }

    @Override
    public FileLogVO imgCompress(FileInfoVO fileInfoVO) {
        FileLogVO fileLogVO = new FileLogVO();
        fileLogVO.setCode(0);
        fileLogVO.setFileReqType(FileReqTypeEnum.IMGCOMPRESS.getType());
        try {
            FileInfoVO fileInfo=null;
            if(fileInfoVO.getFileId()!=null){
                fileInfo=fileInfoIntegration.getFileInfoDetail(fileInfoVO.getFileId());
            }else if(StringUtils.isNotBlank(fileInfoVO.getShowId())){
                fileInfo=fileInfoIntegration.getFileInfoDetail(fileInfoVO.getShowId());
            }else{
                throw new AppException("请传入文件id或文件showId");
            }
            Set<String> imgType=new HashSet<>();
            imgType.add("jpg");
            imgType.add("png");
            imgType.add("jfif");
            imgType.add("jpeg");
            imgType.add("tif");
            imgType.add("bmp");
            if(StringUtils.isBlank(fileInfo.getFileSuffix())||!imgType.contains(fileInfo.getFileSuffix().toLowerCase())){
                //不是图片格式不压缩
                fileLogVO.setMessage("不是图片格式不能压缩");
                return fileLogVO;
            }
            Long fileSize=fileInfo.getFileSize();
            if(fileSize!=null&&fileSize/1024<=100){
                //小于100KB的图片不进行压缩
                fileLogVO.setMessage("小于100KB的图片不进行压缩");
                return fileLogVO;
            }
            FileEnvVO fileEnvVO = fileEnvIntegration.getFileEnvDetail(fileInfo.getFileEnvId());
            if (fileEnvVO == null) {
                throw new AppException("数据异常：文件环境信息未配置");
            }

            // 获取文件分类信息
            FileClassVO fileClassVO =
                    fileClassIntegration.getFileClassDetail(fileInfo.getFileClassCode());
            if (fileClassVO == null) {
                throw new AppException("找不到对应文件分类");
            }
            BeanUtil.copyProperties(fileEnvVO, fileClassVO);
            BeanUtil.copyProperties(fileClassVO, fileInfo);
            fileInfo.setAppId(fileInfoVO.getAppId());
            fileInfo.setReqIp(fileInfoVO.getReqIp());
            fileInfo.setAccessToken(fileInfoVO.getAccessToken());
            fileInfo.setImgCompressDel(fileInfoVO.getImgCompressDel());
            if(fileInfoVO.getUploaderFlag()!=null){
                fileInfo.setUploaderFlag(fileInfoVO.getUploaderFlag());
            }
            if(fileInfoVO.getForceFlag()!=null){
                fileInfo.setForceFlag(fileInfoVO.getForceFlag());
            }
            setInfo(fileInfo, fileLogVO);

            fileServiceUtil.imgCompress(fileInfo, fileClassVO);

        } catch (AppException e) {
            logger.error("获取文件异常：", e);
            fileLogVO.setCode(-1);
            fileLogVO.setMessage(e.getMsg());
        } catch (Exception e) {
            logger.error("获取文件异常：", e);
            fileLogVO.setCode(-1);
            String msg = e.getMessage();
            if (StringUtils.isBlank(msg)) {
                if (e.getCause() != null) {
                    msg = e.getCause().getMessage();
                } else {
                    msg = "系统异常";
                }
            }
            fileLogVO.setMessage(msg);
        }
        fileLogIntegration.saveFileLog(fileLogVO);
        return fileLogVO;
    }

    @Override
    public int batchImgCompress(BatchImgCompressVO batchImgCompressVO) {
        if((batchImgCompressVO.getFileId()!=null&&batchImgCompressVO.getFileId().compareTo(BigDecimal.ZERO)!=0)||StringUtils.isNotBlank(batchImgCompressVO.getShowId())){
            FileInfoVO fileInfoVO=new FileInfoVO();
            fileInfoVO.setFileId(batchImgCompressVO.getFileId());
            fileInfoVO.setShowId(batchImgCompressVO.getShowId());
            fileInfoVO.setAppId(batchImgCompressVO.getAppId());
            fileInfoVO.setImgCompressDel(batchImgCompressVO.getImgCompressDel());
            FileLogVO fileLogVO=this.imgCompress(fileInfoVO);
            if(fileLogVO.getCode()==0){
                return 1;
            }else{
                throw new AppException(fileLogVO.getCode(),fileLogVO.getMessage());
            }
        }
        QueryWrapper<FileInfo> queryWrapper=new QueryWrapper<>();
        boolean flag=true;
        if(batchImgCompressVO.getFileStartId()!=null&&batchImgCompressVO.getFileStartId().compareTo(BigDecimal.ZERO)!=0){
            queryWrapper.lambda().ge(FileInfo::getFileId,batchImgCompressVO.getFileStartId());
            flag=false;
        }
        if(batchImgCompressVO.getFileEndId()!=null&&batchImgCompressVO.getFileEndId().compareTo(BigDecimal.ZERO)!=0){
            queryWrapper.lambda().le(FileInfo::getFileId,batchImgCompressVO.getFileEndId());
            flag=false;
        }
        if(batchImgCompressVO.getUpTimeStart()!=null){
            queryWrapper.lambda().ge(FileInfo::getUpTime,batchImgCompressVO.getUpTimeStart());
            flag=false;
        }
        if(batchImgCompressVO.getUpTimeEnd()!=null){
            queryWrapper.lambda().le(FileInfo::getUpTime,batchImgCompressVO.getUpTimeEnd());
            flag=false;
        }
        if (flag){
            throw new AppException("请先输入查询条件");
        }
        queryWrapper.lambda().orderByAsc(FileInfo::getFileId);
        queryWrapper.lambda().orderByAsc(FileInfo::getUpTime);
        int pageNum=1;
        int pageSize=500;
        int count=0;
        count=getBatchFileInfo(batchImgCompressVO,queryWrapper,pageNum,pageSize,count);
        return count;
    }
    private int getBatchFileInfo(BatchImgCompressVO batchImgCompressVO,QueryWrapper<FileInfo> queryWrapper,int pageNum,int pageSize,int count){
        PageHelper.startPage(pageNum,pageSize);
        List<FileInfo> list=fileInfoService.list(queryWrapper);
        if(CollectionUtils.isEmpty(list)){
            return count;
        }
        PageInfo<FileInfo> pageInfo = new PageInfo<>(list);
        int success=0;
        for(FileInfo fileInfo:pageInfo.getList()){
            FileInfoVO fileInfoVO=new FileInfoVO();
            fileInfoVO.setFileId(fileInfo.getFileId());
            fileInfoVO.setAppId(batchImgCompressVO.getAppId());
            fileInfoVO.setImgCompressDel(batchImgCompressVO.getImgCompressDel());
            FileLogVO fileLogVO=this.imgCompress(fileInfoVO);
            if(fileLogVO.getCode()==0){
                success=success+1;
            }
        }
        count=count+success;
        if (pageInfo.isHasNextPage()){
            pageNum=pageNum+1;
            count=getBatchFileInfo(batchImgCompressVO,queryWrapper,pageNum,pageSize,count);
        }
        return count;
    }

    /** token和权限校验 */
    private void checkTokenAndScope(ApplicationVO apiApplicationVO, String accessToken,String type) {
        if (apiApplicationVO == null) {
            throw new AppException("调用方应用未注册，请先申请注册");
        }
        // 判断是否校验token
        if (BoolEnum.TRUE.getType().equals(apiApplicationVO.getCkeckToken())) {
            Cache cache= JetCacheUtils.create(BaseCache.CACHE_ACCESS_TOKEN, CacheType.BOTH, Duration.ofSeconds(1800), Duration.ofSeconds(60));
            if (cache.get(accessToken)==null) {
                throw new AppException(ErrorEnum.SYSTEM_ERROR_TOKEN);
            }
        }

    }

    /** 根据文件名称获取后缀 输入文件全称, 输出文件后缀 例如： abcde.txt -> txt Or abc.cde$fgh.mp4 -> mp4 */
    private String getFileSuffix(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    }
}
